package com.konsung.ksdc.common.crash;

import android.content.Context;

import com.konsung.ksdc.common.utils.DateUtils;
import com.konsung.ksdc.common.utils.FileUtils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;

/**
 * Created by liangkun on 2017/4/6 0006.
 * 抓取奔溃log的类，路径是sd卡+com.konsung.ksdc
 */

public class CrashHandler implements Thread.UncaughtExceptionHandler {
    private int mPId; //线程id
    // 系统默认的UncaughtException处理类
    protected Thread.UncaughtExceptionHandler mDefaultHandler;
    // CrashHandler实例
    private static CrashHandler crashHandler = new CrashHandler();
    // 程序的Context对象
    private Context mContext;
    protected static String pathCrashLogcat;
    private BufferedWriter bw = null; //写入崩溃后的日志

    /**
     * 保证只有一个CrashHandler实例
     */
    private CrashHandler() {
    }

    /**
     * 获取CrashHandler实例 ,单例模式
     * @return 崩溃类
     */
    public static CrashHandler getInstance() {

        return crashHandler;
    }

    /**
     * 初始化
     * @param context 上下文
     */
    public void init(Context context) {
        mContext = context;
        // 获取系统默认的UncaughtException处理器
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        // 设置该CrashHandler为程序的默认处理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    /**
     * 当UncaughtException发生时会转入该函数来处理
     * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
     * @param ex 异常信息
     */

    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        //打印log日志
        mPId = android.os.Process.myPid();
        // 保存日志文件
        saveCrashInfo2File(ex);
        android.os.Process.killProcess(mPId); //杀死进程，彻底退出程序
        System.exit(1);
    }

    /**
     *保存奔溃日志到文件里
     * @param ex 奔溃日志细心你
     */
    public void saveCrashInfo2File(Throwable ex) {
        //获得实例
        StringBuffer sb = new StringBuffer();
        //写出异常信息
        Writer writer = new StringWriter();
        PrintWriter printWriter = new PrintWriter(writer);
        ex.printStackTrace(printWriter);
        Throwable cause = ex.getCause();
        File dirFile = null;
        while (cause != null) {
            cause.printStackTrace(printWriter);
            cause = cause.getCause();
        }
        printWriter.flush();
        printWriter.close();
        String errString = writer.toString();
        sb.append(errString);
        try {
            //创建包名对应下的文件夹
            if (FileUtils.existSDCard()) {
                // SD卡
                pathCrashLogcat = FileUtils.getSdPath(mContext);
            } else {
                // 本应用的目录
                pathCrashLogcat = FileUtils.getFilePath(mContext);
            }
            File file = new File(pathCrashLogcat);
            if (!file.exists()) {
                file.mkdirs();
            }
            //保存路径文件名
            String path = DateUtils.getDateLog() + ".log";
            //保存路径
            //获得文件
            dirFile = new File(file, path);
            //继续写到log信息到文件里去
            bw = new BufferedWriter(new FileWriter(dirFile, true));
            bw.write(sb.toString());
            bw.flush();
        } catch (Exception e) {
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                    bw = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
